package org.example.gradleauth.security.handler;

import org.example.gradleauth.model.dto.JwtClaimDto;
import org.example.gradleauth.model.factory.AssembleFactory;
import org.example.gradleauth.model.vo.TokenVo;
import org.example.gradleauth.service.TokenService;
import org.example.gradleauth.model.entity.StaffUserDetails;
import gradle.common.core.constants.HeaderConstant;
import gradle.common.core.constants.MediaType;
import gradle.common.core.context.SpringApplicationContext;
import gradle.common.core.response.ApiResponse;
import gradle.common.core.utils.JsonUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.IOException;

/**
 * SuccessHandler
 * Authentication认证成功后 自定义token
 *
 * @author 1141193930@qq.com
 */
public class SecurityAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private final TokenService tokenService = SpringApplicationContext.getBean(TokenService.class);

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

        StaffUserDetails principal = (StaffUserDetails) authentication.getPrincipal();
        JwtClaimDto jwtClaimDto = AssembleFactory.buildJwtClaim(principal);
        //生成AccessToken
        TokenVo accessToken = tokenService.generateAccessToken(jwtClaimDto);

        // REMEMBER_ME 生成 refreshToken
        String header = request.getHeader(HeaderConstant.REMEMBER_ME);
        if (Boolean.parseBoolean(header)) {
            TokenVo refreshToken = tokenService.generateRefreshToken(jwtClaimDto);

            accessToken.setRefreshToken(refreshToken.getRefreshToken());
            accessToken.setRefreshTokenExpiresAt(refreshToken.getRefreshTokenExpiresAt());
        }

        //构建返回ApiResponse
        ApiResponse<Object> success = ApiResponse.success(accessToken);

        //writer
        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        response.getWriter().write(JsonUtil.toJsonString(success));
    }
}
